#ifndef _ESPASYNCWEBSERVER_H_
#define _ESPASYNCWEBSERVER_H_

#include <functional>
#include "StringArray.h"
#include "AsyncServer.hpp"
#include "esp_littlefs.h"

class AsyncWebServer;
class AsyncWebServerRequest;
class AsyncWebServerResponse;
class AsyncWebHeader;
class AsyncWebParameter;
class AsyncWebRewrite;
class AsyncWebHandler;
class AsyncStaticWebHandler;
class AsyncCallbackWebHandler;
class AsyncResponseStream;

typedef enum {
    HTTP_GET     = 0b00000001,
    HTTP_POST    = 0b00000010,
    HTTP_DELETE  = 0b00000100,
    HTTP_PUT     = 0b00001000,
    HTTP_PATCH   = 0b00010000,
    HTTP_HEAD    = 0b00100000,
    HTTP_OPTIONS = 0b01000000,
    HTTP_ANY     = 0b01111111,
} WebRequestMethod;
#define RESPONSE_TRY_AGAIN  0xFFFFFFFF

using WebRequestMethodComposite = uint8_t;
using ArDisconnectHandler = std::function<void(void)>;

/// 存储HTTP请求（GET/POST/FILE）中的参数名称、值、类型（表单/文件）及大小
/// 支持链式存储
class AsyncWebParameter {
public:
    AsyncWebParameter(const std::string &name, const std::string &value, bool form = false, bool file = false, size_t size = 0)
        : m_name(name)
        , m_value(value)
        , m_size(size)
        , m_isForm(form)
        , m_isFile(file)
    {}
    const std::string &name() const
    {
        return m_name;
    }
    const std::string &value() const
    {
        return m_value;
    }
    size_t size() const
    {
        return m_size;
    }
    bool isPost() const
    {
        return m_isForm;
    }
    bool isFile() const
    {
        return m_isFile;
    }
private:
    std::string  m_name;     // 参数名称
    std::string  m_value;    // 参数值
    size_t  m_size;     // 文件大小，仅对文件生效
    bool    m_isForm;   // 参数是否来自POST表单数据
    bool    m_isFile;   // 参数是否为上传的文件
};

/// 用于封装 HTTP 头信息，将请求或响应中的头字段（如 Content-Type、Cookie、User-Agent 等）以结构化的方式存储和管理。
/// 支持链式存储
class AsyncWebHeader {
public:
    AsyncWebHeader(const std::string &name, const std::string &value)
        : m_name(name)
        , m_value(value)
    {}
    AsyncWebHeader(const std::string &data)
        : m_name()
        , m_value()
    {
        if (data.empty()) {
            return;
        }
        size_t index = data.find(':');
        if (index == std::string::npos) {
            return;
        }
        m_name = data.substr(0, index);
        m_value = data.substr(index + 2);
    }
    ~AsyncWebHeader() {}

    const std::string &name() const
    {
        return m_name;
    }
    const std::string &value() const
    {
        return m_value;
    }
    std::string toString() const
    {
        return std::string(m_name + ": " + m_value + "\r\n");
    }

private:
    std::string  m_name;
    std::string  m_value;
};

/// @brief 标识客户端与服务器之间不同类型的连接或请求类型
enum RequestedConnectionType {
    RCT_NOT_USED = -1,  // 未使用的连接类型
    RCT_DEFAULT = 0,    // 默认连接类型，通常表示未明确指定协议的请求
    RCT_HTTP,           // 标准的 HTTP 连接（如 GET/POST 请求）
    RCT_WS,             // WebSocket 连接（用于实时双向通信）
    RCT_EVENT,          // 表示事件流（如 Server-Sent Events, SSE）或其他自定义事件协议
    RCT_MAX             // 枚举的最大值，循环遍历所有有效枚举值
};

using AwsResponseFiller = std::function<size_t(uint8_t*, size_t, size_t)>;
using AwsTemplateProcessor = std::function<std::string(const std::string &)>;

/// 封装和处理单个 HTTP 请求的完整生命周期和相关信息。它是客户端请求的抽象表示，
/// 负责解析请求内容、管理参数、头信息，并协调生成响应。
class AsyncWebServerRequest {
private:
    friend class AsyncWebServer;
    friend class AsyncCallbackWebHandler;

public:
    std::string m_fileName;     // 文件名
    void        *_tempObject;

    AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c);
    ~AsyncWebServerRequest();

    AsyncClient* client();
    uint8_t version() const;
    WebRequestMethodComposite method() const;
    const std::string &url() const;
    const std::string &host() const;
    const std::string &contentType() const;
    size_t contentLength() const;
    bool multipart() const;
    const char* methodToString() const;
    const char* requestedConnTypeToString() const;
    RequestedConnectionType requestedConnType() const;
    bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED);
    void onDisconnect(ArDisconnectHandler fn);

    bool authenticate(const char* hash);
    bool authenticate(const char* username, const char* password, const char* realm = nullptr, bool passwordIsHash = false);
    void requestAuthentication(const char* realm = nullptr, bool isDigest = true);

    void setHandler(AsyncWebHandler* handler);
    void addInterestingHeader(const std::string &name);

    void redirect(const std::string &url);

    void send(AsyncWebServerResponse* response);
    void send(int code, const std::string &contentType = std::string(), const std::string &content = std::string());
    void send(const std::string &path, const std::string &contentType = std::string(), bool download = false, AwsTemplateProcessor callback = nullptr);
    void send(const std::string &contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
    void sendChunked(const std::string &contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
    void send_P(int code, const std::string &contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr);

    AsyncWebServerResponse *beginResponse(int code, const std::string &contentType = std::string(), const std::string &content = std::string());
    AsyncWebServerResponse *beginResponse(const std::string &path, const std::string &contentType = std::string(), bool download = false, AwsTemplateProcessor callback = nullptr);
    AsyncWebServerResponse *beginResponse(const std::string &contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
    AsyncWebServerResponse *beginChunkedResponse(const std::string &contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
    AsyncResponseStream *beginResponseStream(const std::string &contentType, size_t bufferSize = 1460);
    AsyncWebServerResponse *beginResponse_P(int code, const std::string &contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback = nullptr);

    size_t headers() const;
    bool hasHeader(const std::string &name) const;

    AsyncWebHeader* getHeader(const std::string &name) const;
    AsyncWebHeader* getHeader(size_t index) const;

    size_t params() const;
    bool hasParam(const std::string &name, bool post = false, bool file = false) const;

    AsyncWebParameter* getParam(const std::string &name, bool post = false, bool file = false) const;
    AsyncWebParameter* getParam(size_t index) const;

    size_t args() const;
    const std::string &arg(const std::string &name) const;
    const std::string &arg(size_t index) const;
    const std::string &argName(size_t index) const;
    bool hasArg(const char* name) const;

    // const std::string& ASYNCWEBSERVER_REGEX_ATTRIBUTE pathArg(size_t i) const;

    const std::string &header(const char* name) const;
    const std::string &header(size_t index) const;
    const std::string &headerName(size_t index) const;
    std::string urlDecode(const std::string &text) const;

private:
    AsyncClient* m_client;                  // 指向客户端的指针，表示与服务器的TCP连接
    AsyncWebServer* m_server;               // 指向所属的服务器，用于协调服务器操作
    AsyncWebHandler* m_handler;             // 处理该请求的处理器
    AsyncWebServerResponse* m_response;     // 当前请求的响应对象
    StringArray m_interestingHeaders;       // 关注的请求头
    ArDisconnectHandler m_onDisconnectfn;

    std::string m_temp;
    uint8_t m_parseState;

    uint8_t m_version;
    WebRequestMethodComposite m_method;     // 请求的方法
    std::string m_url;                           // 请求的URL
    std::string m_host;                          // 请求的HOST
    std::string m_contentType;                   // 请求的内容类型（如application/json)
    std::string m_boundary;                      // boundary边界字符串
    std::string m_authorization;                 // 请求中的认证字段
    RequestedConnectionType m_reqconntype;  // 连接类型
    void m_removeNotInterestingHeaders();
    bool m_isDigest;                        // 是否为Digest认证
    bool m_isMultipart;                     // 是否为多部分表单标记
    bool m_isPlainPost;                     // 是否为表单数据
    bool m_expectingContinue;               // 客户端在接收到服务器100 Continue响应后再发送请求体内容
    size_t m_contentLength;                 // 请求体的字节数（POST数据或文件）
    size_t m_parsedLength;                  // 请求体中处理的字节计数

    LinkedList<AsyncWebHeader*> m_headers;      // 所有的请求头
    LinkedList<AsyncWebParameter*> m_params;    // 存储请求参数（如请求参数、表单数据、文件）
    LinkedList<std::string*> m_pathParams;

    uint8_t m_multiParseState;      // 解析多部分表单数据时所处的状态
    uint8_t m_boundaryPosition;     // 当前边界字符串匹配的位置
    size_t  m_itemStartIndex;       // 当前处理的部分在原始数据中的起始位置
    size_t  m_itemSize;             // 当前正处理的部分的大小
    std::string  m_itemName;             // 当前部分的名称
    std::string  m_itemFilename;         // 当前部分是文件时，存储该文件的名称
    std::string  m_itemType;             // 当前部分的内容类型
    std::string  m_itemValue;       // 对于非文件类型的表单数据存储其值
    uint8_t *m_itemBuffer;          // 存储当前部分数据的缓冲区
    size_t  m_itemBufferIndex;      // 缓冲区中已使用的字节数
    bool    m_itemIsFile;           // 标识当前部分是否为文件

    void m_onPoll();
    void m_onAck(size_t len, uint64_t time);
    void m_onErr(err_t error);
    void m_onTimeout(uint64_t time);
    void m_onDisconnect();
    void m_onData(void* buf, size_t len);

    // 添加web参数
    void m_addParam(AsyncWebParameter* p);
    void m_addPathParam(const char* param);

    bool m_parseReqHead();
    bool m_parseReqHeader();
    void m_parseLine();
    void m_parsePlainPostChar(uint8_t data);
    void m_parseMultipartPostByte(uint8_t data, bool last);
    void m_addGetParams(const std::string &params);

    void m_handleUploadStart();
    void m_handleUploadByte(uint8_t data, bool last);
    void m_handleUploadEnd();
};

using ArRequestFilterFunction = std::function<bool(AsyncWebServerRequest* req)>;
/// 处理URL重写的类
class AsyncWebRewrite {
protected:
    std::string m_from;                 // 原始URL
    std::string m_toUrl;                // 被重定向后的URL
    std::string m_params;               // 附加在目标URL后的参数
    ArRequestFilterFunction m_filter;   // 过滤函数
public:
    AsyncWebRewrite(const char* from, const char* to)
        : m_from(from), m_toUrl(to), m_filter(nullptr)
    {
        size_t index = m_toUrl.find('?');
        if (index != std::string::npos) {
            m_params = m_toUrl.substr(index + 1);
            m_toUrl = m_toUrl.substr(0, index);
        }
    }
    virtual ~AsyncWebRewrite() {}
    // 设置重写匹配函数
    AsyncWebRewrite &setFilter(ArRequestFilterFunction fn)
    {
        m_filter = fn;
        return *this;
    }
    // 判断能否通过匹配函数检查
    bool filter(AsyncWebServerRequest* req) const
    {
        return m_filter == nullptr || m_filter(req);
    }
    // 返回原始URL变量的引用
    const std::string &from(void) const
    {
        return m_from;
    }
    // 返回目标URL变量的引用
    const std::string &toUrl(void) const
    {
        return m_toUrl;
    }
    // 返回请求参数的引用
    const std::string &params(void) const
    {
        return m_params;
    }
    // 判断给定的请求是否符合重写规则
    virtual bool match(AsyncWebServerRequest* req)
    {
        return m_from == req->url() && m_filter && m_filter(req);
    }
};

using ArRequestFilterFunction = std::function<bool(AsyncWebServerRequest* req)>;
// 处理器
class AsyncWebHandler {
public:
    AsyncWebHandler() : m_username(""), m_password("") {}
    // 设置过滤函数
    AsyncWebHandler &setFileter(ArRequestFilterFunction fn)
    {
        m_filter = fn;
        return *this;
    }
    // 设置用于认证的用户名、密码
    AsyncWebHandler &setAuthentication(const char* name, const char* passwd)
    {
        m_username = std::string(name);
        m_password = std::string(passwd);
        return *this;
    }

    /// @brief 根据设置的过滤回调对请求过滤
    /// @return 可以被处理时返回true
    bool filter(AsyncWebServerRequest* req)
    {
        return m_filter == nullptr || m_filter(req);
    }

    virtual ~AsyncWebHandler() {}
    virtual bool canHandle(AsyncWebServerRequest* req __attribute__((unused)))
    {
        return false;
    }
    virtual void handleRequest(AsyncWebServerRequest* req __attribute__((unused))) {}
    virtual void handleUpload(AsyncWebServerRequest *request  __attribute__((unused)),
                              const std::string &filename __attribute__((unused)),
                              size_t index __attribute__((unused)),
                              uint8_t *data __attribute__((unused)),
                              size_t len __attribute__((unused)),
                              bool final  __attribute__((unused)))
    {}
    virtual void handleBody(AsyncWebServerRequest *request __attribute__((unused)),
                            uint8_t *data __attribute__((unused)),
                            size_t len __attribute__((unused)),
                            size_t index __attribute__((unused)),
                            size_t total __attribute__((unused)))
    {}

    /// @brief 返回当前处理器是否执行用户自定义处理逻辑
    /// @return
    virtual bool isRequestHandlerTrivial()
    {
        return true;
    }

protected:
    ArRequestFilterFunction  m_filter;
    std::string  m_username;
    std::string  m_password;
};

using ArRequestHandlerFunction = std::function<void(AsyncWebServerRequest *request)>;
using ArUploadHandlerFunction = std::function<void(AsyncWebServerRequest *request, const std::string &filename, size_t index, uint8_t *data, size_t len, bool final)>;
using ArBodyHandlerFunction = std::function<void(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)>;

enum WebResponseState { // 响应的生命周期状态
    RESPONSE_SETUP,     // 初始化阶段
    RESPONSE_HEADERS,   // 发送头信息阶段
    RESPONSE_CONTENT,   // 发送内容阶段
    RESPONSE_WAIT_ACK,  // 等待客户端确认（ACK）
    RESPONSE_END,       // 响应结束
    RESPONSE_FAILED     // 响应失败
};

class AsyncWebServerResponse {
protected:
    int     m_code;                         // HTTP状态码
    LinkedList<AsyncWebHeader*> m_headers;  // 存储所有响应头
    std::string  m_contentType;             // 内容类型
    size_t  m_contentLength;                // 响应内容总长度
    bool    m_sendContentLength;            // 是否发送Content-Length头（让客户端知道内容长度）
    bool    m_chunked;                      // 是否使用分块传输编码（内容长度未知时使用）
    size_t  m_headLength;                   // 已发送的头信息长度
    size_t  m_sentLength;                   // 已发送的总字节数
    size_t  m_ackedLength;                  // 客户端确认接收的字节数（用于流控）
    size_t  m_writtenLength;                // 写入到客户端的数据长度
    WebResponseState    m_state;            // 当前响应所处的状态
    const char* m_responseCodeToString(int code);

public:
    AsyncWebServerResponse();
    virtual ~AsyncWebServerResponse();
    virtual void setCode(int code);
    virtual void setContentLength(size_t len);
    virtual void setContentType(const std::string &type);
    virtual void addHeader(const std::string &name, const std::string &value);
    virtual std::string _assembleHead(uint8_t version);
    virtual bool _started() const;
    virtual bool _finished() const;
    virtual bool _failed() const;
    virtual bool _sourceValid() const;
    virtual void _respond(AsyncWebServerRequest* req);
    virtual size_t _ack(AsyncWebServerRequest* req, size_t len, uint64_t time);
};

class AsyncWebServer {
protected:
    AsyncServer m_server;                               // 异步TCP服务器
    LinkedList<AsyncWebRewrite*>    m_rewrites;         // URL重写链表
    LinkedList<AsyncWebHandler*>    m_handlers;         // HTTP处理器链表
    AsyncCallbackWebHandler*        m_catchAllHandler;  // 处理未匹配处理器的请求的处理器
public:
    AsyncWebServer(uint16_t port);
    ~AsyncWebServer();

    void begin();
    void end();

    AsyncWebRewrite &addRewrite(AsyncWebRewrite* rewrite);
    bool removeRewrite(AsyncWebRewrite* rewrite);
    AsyncWebRewrite &rewrite(const char* from, const char* to);

    AsyncWebHandler &addHandler(AsyncWebHandler* handler);
    bool removeHandler(AsyncWebHandler* handler);

    AsyncCallbackWebHandler &on(const char* uri, ArRequestHandlerFunction onRequest);
    AsyncCallbackWebHandler &on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest);
    AsyncCallbackWebHandler &on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload);
    AsyncCallbackWebHandler &on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody);

    AsyncStaticWebHandler &serveStatic(const char* uri, const char* path, const char* cache_control);

    void onNotFound(ArRequestHandlerFunction fn);
    void onFileUpload(ArUploadHandlerFunction fn);
    void onRequestBody(ArBodyHandlerFunction fn);

    void reset();

    void _handleDisconnect(AsyncWebServerRequest* req);
    void _attachHandler(AsyncWebServerRequest* req);
    void _rewriteRequest(AsyncWebServerRequest* req);
};

class DefaultHeaders {
    using headers_t = LinkedList<AsyncWebHeader*>;
    headers_t m_headers;
    DefaultHeaders()
        : m_headers(headers_t([](AsyncWebHeader * h)
    {
        delete h;
    }))
    {}
public:
    using ConstIterator = headers_t::ConstIterator;

    void addHeader(const std::string &name, const std::string &value)
    {
        m_headers.add(new AsyncWebHeader(name, value));
    }

    ConstIterator begin() const
    {
        return m_headers.begin();
    }
    ConstIterator end() const
    {
        return m_headers.end();
    }
    DefaultHeaders(DefaultHeaders const &) = delete;
    DefaultHeaders &operator=(DefaultHeaders const &) = delete;
    static DefaultHeaders &Instance()
    {
        static DefaultHeaders instance;
        return instance;
    }
};

#include "WebResponseImpl.h"
#include "WebHandlerImpl.h"
// #include "AsyncWebSocket.h"
// #include "AsyncEventSource.h"

#endif // !_ESPASYNCWEBSERVER_H_
